package com.hxht.cmp.service.impl;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.hxht.cmp.common.BasisConfig;
import com.hxht.cmp.common.Constants;
import com.hxht.cmp.entity.*;
import com.hxht.cmp.mapper.*;
import com.hxht.cmp.pojo.BasisCourt;
import com.hxht.cmp.pojo.CourtCoordinate;
import com.hxht.cmp.pojo.CourtroomCfg;
import com.hxht.cmp.pojo.CourtroomEx;
import com.hxht.cmp.service.BasisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * @author alice on 2017/6/29 0029.
 * @version 1.1
 * @since 1.0
 */
@Service
public class BasisServiceImp implements BasisService {
    private final Logger log = LoggerFactory.getLogger(BasisService.class);
    @Resource
    private DictMapper dictMapper;
    @Resource
    private CourtMapper courtMapper;
    @Resource
    private CaseTypeMapper caseTypeMapper;
    @Resource
    private CourtRoomMapper courtRoomMapper;
    @Resource
    private RoleMapper roleMapper;

    @PostConstruct
    public void init() throws Exception {
        synchronized (this) {
            flushDict();
            Constants.COURT_LIST = getCourt();
            for (Court court : Constants.COURT_LIST) {
                Constants.COURT_MAP.put(court.getUid(), court);
            }
            flushCourtConfig();
            flushCourtCoordinate();
            List<CourtRoom> courtRooms = getCourtRoom(null);
            Gson gson = new Gson();
            Constants.COURTROOM_LIST.clear();
            Constants.COURTROOM_MAP.clear();
            for (CourtRoom courtRoom : courtRooms) {
                CourtroomEx courtroomEx = new CourtroomEx(courtRoom);
                if (!ObjectUtils.isEmpty(courtRoom.getCfg())) {
                    try {
                        JsonArray jsonArray = gson.fromJson(courtRoom.getCfg(), JsonArray.class);
                        for (JsonElement jsonElement : jsonArray) {
                            CourtroomCfg courtroomCfg = gson.fromJson(jsonElement, CourtroomCfg.class);
                            courtroomEx.addConfig(courtroomCfg);
                        }
                    }catch (Exception e) {
                        log.error("转换cfg出现问题,法庭: "+ courtRoom.getId()+" 错误信息: "+e.getMessage());
                    }
                }
                Constants.COURTROOM_LIST.add(courtroomEx);
            }
            for (CourtroomEx courtRoom : Constants.COURTROOM_LIST) {
                Constants.COURTROOM_MAP.put(courtRoom.getUid(), courtRoom);
            }
            Constants.CASE_TYPE_MAP.clear();
            Constants.CASE_TYPE_LIST = getCaseType(null);
            for (CaseType caseType : Constants.CASE_TYPE_LIST) {
                Constants.CASE_TYPE_MAP.put(caseType.getUid(), caseType);
            }
            Constants.ROLE_LIST = getRole(null);
        }
    }

    @Override
    public Boolean flushDict() {
        Example dict = new Example(Dict.class);
        dict.createCriteria().andCondition("dict_code=", BasisConfig.SYSTEM_CONFIG).andNotEqualTo("state", 4);
        List<Dict> result = dictMapper.selectByExample(dict);
        if (!ObjectUtils.isEmpty(result)) {
            Example basis = new Example(Dict.class);
            basis.createCriteria().andCondition("parent_dict_id=", result.get(0).getId()).andNotEqualTo("state", 4);
            List<Dict> configList = dictMapper.selectByExample(basis);
            synchronized (this) {
                try {
                    String tempCourtId = "";
                    for (Dict config : configList) {
                        switch (config.getDictCode()) {
                            case "SYSTEM_LOCKED":
                                Constants.SYSTEM_LOCKED = Integer.parseInt(config.getDictVal());
                                break;
                            case "LOGIN_NUM":
                                Constants.LOGIN_NUM = Integer.parseInt(config.getDictVal());
                                break;
                            case "CENTRAL_COURT":
                                tempCourtId = config.getDictVal();
                                break;
                            case "CENTRAL_PORT":
                                Constants.CENTRAL_PORT = config.getDictVal();
                                break;
                            case "CENTRAL_IP":
                                Constants.CENTRAL_IP = config.getDictVal();
                                break;
                            case "SERVER_PORT":
                                Constants.SERVER_PORT = config.getDictVal();
                                break;
                            case "DOWNLOAD_USER":
                                Constants.DOWNLOAD_USER = config.getDictVal();
                                break;
                            case "DOWNLOAD_PASSWORD":
                                Constants.DOWNLOAD_PASSWORD = config.getDictVal();
                                break;
                            case "DOWNLOAD_PORT":
                                Constants.DOWNLOAD_PORT = config.getDictVal();
                                break;
                            case "DOWNLOAD_DIR":
                                Constants.DOWNLOAD_DIR = config.getDictVal();
                                break;
                            case "FFMPEG_DIR":
                                Constants.FFMPEG_DIR = config.getDictVal();
                                break;
                            case "COURT_SUM":
                                Constants.COURT_SUM = Integer.parseInt(config.getDictVal());
                                break;
                            case "ON_TIME":
                                Constants.ON_TIME_BEFORE = Integer.parseInt(config.getDictVal());
                                Constants.ON_TIME_AFTER = Integer.parseInt(config.getExt1());
                                break;
                            case "MAJOR_UPLOAD_PATH":
                                Constants.MAJOR_PATH = config.getDictVal();
                                break;
                            default:
                                break;
                        }
                    }
                    Court court = new Court();
                    court.setCode(tempCourtId);
                    court = courtMapper.selectOne(court);
                    Constants.CENTRAL_COURT = court;
                    Constants.SERVER_IP = court.getServiceIp();
                } catch (Exception e) {
                    log.error("基础配置赋值时发生严重错误" + e.getMessage());
                    Constants.SYSTEM_LOCKED = 1;
                    return false;
                }
            }
            return true;
        } else {
            log.error("警告,查询基础配置出现严重错误!请确认数据库配置正确无误!");
            Constants.SYSTEM_LOCKED = 1;
            return false;
        }
    }

    private void flushCourtConfig() throws Exception {
        Example dict = new Example(Dict.class);
        dict.createCriteria().andCondition("dict_code=", BasisConfig.COURT_CONFIG).andNotEqualTo("state", 4);
        List<Dict> result = dictMapper.selectByExample(dict);
        if (!ObjectUtils.isEmpty(result)) {
            Example courtExample = new Example(Dict.class);
            courtExample.createCriteria().andCondition("parent_dict_id=", result.get(0).getId()).andNotEqualTo("state", 4);
            List<Dict> configList = dictMapper.selectByExample(courtExample);
            Constants.COURT_CONFIG_LIST.clear();
            for (Dict dict1 : configList) {
                Court court = Constants.COURT_MAP.get(dict1.getExt5());
                if (ObjectUtils.isEmpty(court)) {
                    continue;
                }
                BasisCourt basisCourt = new BasisCourt();
                basisCourt.setUid(court.getUid());
                basisCourt.setCode(court.getCode());
                basisCourt.setName(court.getName());
                basisCourt.setNum(court.getNum());
                basisCourt.setLevel(court.getLevel());
                basisCourt.setSequence(court.getSequence());
                basisCourt.setServiceIp(court.getServiceIp());
                basisCourt.setParentUid(court.getParentUid());
                basisCourt.setShortName(court.getShortName());
                basisCourt.setAbbreviation(dict1.getDictVal());
                basisCourt.setAllCourtNum(Integer.parseInt(dict1.getExt1()));
                basisCourt.setTechnicalCourtNum(Integer.parseInt(dict1.getExt2()));
                if (!ObjectUtils.isEmpty(dict1.getExt4())) {
                    basisCourt.setNavigationName(dict1.getExt4());
                } else {
                    basisCourt.setNavigationName(court.getName());
                }
                basisCourt.setThirdCourtNum(Integer.parseInt(dict1.getExt3()));
                Constants.COURT_CONFIG_LIST.add(basisCourt);
            }
            Constants.COURT_CONFIG_LIST.sort(Comparator.comparing(BasisCourt::getLevel).thenComparing(Comparator.comparing(BasisCourt::getSequence)));
        }
    }

    private void flushCourtCoordinate() throws Exception {
        Example dict = new Example(Dict.class);
        dict.createCriteria().andCondition("dict_code=", BasisConfig.COURT_MAP_CONFIG).andNotEqualTo("state", 4);
        List<Dict> result = dictMapper.selectByExample(dict);
        if (!ObjectUtils.isEmpty(result)) {
            Example courtExample = new Example(Dict.class);
            courtExample.createCriteria().andCondition("parent_dict_id=", result.get(0).getId()).andNotEqualTo("state", 4);
            List<Dict> configList = dictMapper.selectByExample(courtExample);
            Constants.COURT_COORDINATE_LIST.clear();
            for (Dict dict1 : configList) {
                CourtCoordinate courtCoordinate = new CourtCoordinate();
                courtCoordinate.setCourtUid(dict1.getExt5());
                Court court = Constants.COURT_MAP.get(dict1.getExt5());
                if (ObjectUtils.isEmpty(court)) {
                    continue;
                }
                courtCoordinate.setParentUid(court.getParentUid());
                String[] location = dict1.getDictVal().split(",");
                if (!ObjectUtils.isEmpty(location) && location.length == 2) {
                    courtCoordinate.setLng(location[0]);
                    courtCoordinate.setLat(location[1]);
                } else {
                    courtCoordinate.setLng("");
                    courtCoordinate.setLat("");
                }
                Constants.COURT_COORDINATE_LIST.add(courtCoordinate);
            }
        }
    }


    @Override
    public List<Court> getCourt() {
        if (Constants.CENTRAL_COURT.getLevel() == 1) {
            String indexCourt = Constants.CENTRAL_COURT.getCode().substring(0, Constants.CENTRAL_COURT.getLevel());
            Example example = new Example(Court.class);
            example.createCriteria().andCondition("code like '" + indexCourt + "%'");
            example.setOrderByClause("level,sequence");
            example.setDistinct(false);
            return courtMapper.selectByExample(example);
        }
        List<Court> courts = new ArrayList<>();
        if (Constants.CENTRAL_COURT.getLevel() == 2) {
            courts.add(Constants.CENTRAL_COURT);
            Court court = new Court();
            court.setParentUid(Constants.CENTRAL_COURT.getUid());
            courts.addAll(courtMapper.select(court));
            return courts;
        } else if (Constants.CENTRAL_COURT.getLevel() == 3) {
            courts.add(Constants.CENTRAL_COURT);
            return courts;
        }
        return null;
    }

    @Override
    public List<CourtRoom> getCourtRoom(CourtRoom courtRoom) {
        return courtRoomMapper.select(courtRoom);
    }

    @Override
    public List<CaseType> getCaseType(CaseType caseType) {
        return caseTypeMapper.select(caseType);
    }

    @Override
    public List<Role> getRole(Role role) {
        Example example = new Example(Role.class);
        example.setOrderByClause("sequence desc");
        example.setDistinct(false);
        return roleMapper.selectByExample(example);
    }
}
